package com.yihen.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.yihen.dto.AddBillAndRegistrationDto;
import com.yihen.dto.Result;
import com.yihen.pojo.Bill;
import com.yihen.pojo.Patient;
import com.yihen.pojo.Registration;
import com.yihen.service.BillService;
import com.yihen.service.CoreAddSerice;
import com.yihen.service.PatientService;
import com.yihen.service.RegistrationService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.Constants;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class CoreAddSericeImpl implements CoreAddSerice {
    @Autowired
    private PatientService patientService;
    @Autowired
    private DoctorServiceImpl doctorService;
    @Autowired
    private BillService billService;
    @Autowired
    private RegistrationService registrationService;
    // 阻塞队列
    private BlockingQueue<Patient> patientTasks = new ArrayBlockingQueue<>(1024 * 1024);
    // 线程池
    private static final ExecutorService PATIENTEXECUTOR = Executors.newFixedThreadPool(10);

    @PostConstruct
    private void init() {
        PATIENTEXECUTOR.submit(new PatientHandler());
    }
    // 处理患者添加
    private class PatientHandler implements Runnable{
        @SneakyThrows
        @Override
        public void run() {
            while (true) {
                // 获取任务
                Patient patient = patientTasks.take();
                Result patientById = patientService.getPatientById(patient.getId());
                // 没有该患者说明是第一次来诊所，要入库
                if (patientById.getData() == null) {
                    patientService.addPatient(patient);
                }
            }
        }
    }

    @Override
    @Transactional
    public Result addRegistrationAndBill(AddBillAndRegistrationDto dto) {
        // 判断医生身份证号是否存在
        Result doctorById = doctorService.getDoctorById(dto.getDoctorId());
        if (doctorById.getData() == null) {
            return new Result("医生身份证号不存在！");
        }
        // 计算总费用
        dto.setCost(dto.getDrugFee() + dto.getOfficeVisFee());
        // 将dto转换为map
        Map<String, Object> map = BeanUtil.beanToMap(dto);
        // 属性注入
        Bill bill = BeanUtil.fillBeanWithMap(map, new Bill(), false);
        Registration registration = BeanUtil.fillBeanWithMap(map, new Registration(), false);
        // 生成唯一id号
        long registrationId = IdUtil.getSnowflake(1, 1).nextId();
        long billId = IdUtil.getSnowflake(1, 1).nextId();
        // 填充id
        bill.setRegistrationId(registrationId);
        bill.setId(billId);
        registration.setBillId(billId);
        registration.setId(registrationId);
        // 生成患者对象
        Patient patient = new Patient();
        patient.setGender(dto.getGender());
        patient.setName(dto.getPatientName());
        patient.setId(dto.getPatientId());
        // 交给其他线程处理患者对象
        patientTasks.add(patient);
        // 添加挂号信息和账单信息
        billService.addBill(bill);
        registrationService.addRegistration(registration);
        return new Result(null, true, Constants.ADDSUCCESS);
    }
}
